package com.tanhua.dubbo.api;


import com.tanhua.model.domain.UserLike;
import com.tanhua.model.dto.LikeCount;
import com.tanhua.model.mongo.CommonLikeUser;
import com.tanhua.model.mongo.Friend;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.PageResult;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@DubboService
public class UserLikeApiImpl implements UserLikeApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 左滑右滑,喜不喜欢
     *
     * @param userId
     * @param likeUserId
     * @param isLike
     * @return
     */
    @Override
    public Boolean saveOrUpdate(Long userId, Long likeUserId, boolean isLike) {
        try {
            //1、查询数据
            Query query = Query.query(Criteria.where("userId").is(userId).and("likeUserId").is(likeUserId));
            UserLike userLike = mongoTemplate.findOne(query, UserLike.class);
            //2、如果不存在，保存
            if (userLike == null) {
                userLike = new UserLike();
                userLike.setUserId(userId);
                userLike.setLikeUserId(likeUserId);
                userLike.setCreated(System.currentTimeMillis());
                userLike.setUpdated(System.currentTimeMillis());
                userLike.setIsLike(isLike);
                mongoTemplate.save(userLike);
            } else {
                //3、更新
                Update update = Update.update("isLike", isLike)
                        .set("updated", System.currentTimeMillis());
                mongoTemplate.updateFirst(query, update, UserLike.class);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 统计喜欢数
     *
     * @param userId
     * @return
     */
    @Override
    public LikeCount counts(Long userId) {
        //1.我喜欢的
        Query query = new Query(Criteria.where("userId").is(userId));
        long ideo = mongoTemplate.count(query, UserLike.class);

        //2.喜欢我的
        Query query1 = new Query(Criteria.where("likeUserId").is(userId));
        long fans = mongoTemplate.count(query1, UserLike.class);

        //3.相互喜欢的:查询好友表
        Query query2 = new Query(Criteria.where("userId").is(userId));
        long friend = mongoTemplate.count(query2, Friend.class);

        //4.构造返回值
        LikeCount likeCounts = new LikeCount();
        likeCounts.setEachLoveCount((int) friend);
        likeCounts.setFanCount((int) fans);
        likeCounts.setLoveCount((int) ideo);

        return likeCounts;
    }

    /**
     * 分页查询好友列表（相互喜欢列表）
     *
     * @param userId   用户id
     * @param page     页码
     * @param pagesize 查询几条
     * @return
     */
    @Override
    public PageResult<CommonLikeUser> queryFriendsList(Long userId, Integer page, Integer pagesize) {
        //1.根据id查询分页数据数据
        Query query = new Query(Criteria.where("userId").is(userId))
                .with(Sort.by(Sort.Order.desc("created")))
                .with(PageRequest.of(page - 1, pagesize));
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);
        //2.总记录数
        long count = mongoTemplate.count(query, Friend.class);

        //3.stream封装数据收集
        List<CommonLikeUser> commonLikeUsers = friendList.parallelStream().map(friend -> {
            CommonLikeUser likeUser = new CommonLikeUser();
            likeUser.setTargetUserId(friend.getFriendId());
            likeUser.setScore(queryScore(userId, likeUser.getTargetUserId()));
            return likeUser;
        }).collect(Collectors.toList());

        //总页数
        Integer pages = (int) Math.ceil(count * 1.0 / pagesize);

        //4.构造返回
        return new PageResult<>(count, pagesize, pages, page, commonLikeUsers);
    }


    /**
     * 分页查询喜欢的用户列表
     *
     * @param userId   用户id
     * @param page     页码
     * @param pagesize 查询几条
     * @return
     */
    @Override
    public PageResult<CommonLikeUser> queryLikeList(Long userId, Integer page, Integer pagesize) {
        //1.根据id查询分页数据数据列表
        Query query = new Query(Criteria.where("userId").is(userId))
                .with(Sort.by(Sort.Order.desc("created")))
                .with(PageRequest.of(page - 1, pagesize));
        List<UserLike> userLikeList = mongoTemplate.find(query, UserLike.class);

        //2.查询总记录数
        long count = mongoTemplate.count(query, UserLike.class);

        //3.封装数据
        ArrayList<CommonLikeUser> commonUserList = new ArrayList<>();
        for (UserLike userLike : userLikeList) {
            CommonLikeUser user = new CommonLikeUser();
            user.setTargetUserId(userLike.getLikeUserId());
            user.setScore(queryScore(userId, user.getTargetUserId()));

            commonUserList.add(user);
        }

        Integer pages = (int) Math.ceil(count * 1.0 / pagesize);
        return new PageResult<>(count, pagesize, pages, page, commonUserList);
    }

    /**
     * 分页查询粉丝列表
     *
     * @param userId   用户id
     * @param page     页码
     * @param pagesize 查询几条
     * @return
     */
    @Override
    public PageResult<CommonLikeUser> queryFansList(Long userId, Integer page, Integer pagesize) {
        Query query = new Query(Criteria.where("likeUserId").is(userId))
                .with(Sort.by(Sort.Order.desc("created")))
                .with(PageRequest.of(page - 1, pagesize));
        List<UserLike> userLikeList = mongoTemplate.find(query, UserLike.class);

        long count = mongoTemplate.count(query, UserLike.class);

        List<CommonLikeUser> commonLikeUserList = new ArrayList<>();
        for (UserLike userLike : userLikeList) {

            CommonLikeUser user = new CommonLikeUser();

            user.setTargetUserId(userLike.getUserId());
            user.setScore(queryScore(userId, user.getTargetUserId()));

            commonLikeUserList.add(user);
        }

        Integer pages = (int) Math.ceil(count * 1.0 / pagesize);
        return new PageResult<>(count, pagesize, pages, page, commonLikeUserList);
    }

    /**
     * 分页查询来访者
     *
     * @param userId   用户id（被访问者）
     * @param page     页码
     * @param pagesize 查询几条
     * @return
     */
    @Override
    public PageResult<CommonLikeUser> findVisitorList(Long userId, Integer page, Integer pagesize) {
        Query query = new Query(Criteria.where("userId").is(userId))
                .with(Sort.by(Sort.Order.desc("date")))
                .with(PageRequest.of(page - 1, pagesize));

        List<Visitors> visitorList = mongoTemplate.find(query, Visitors.class);
        long count = mongoTemplate.count(query, Visitors.class);

        List<CommonLikeUser> commonUserList = new ArrayList<>();
        for (Visitors visitor : visitorList) {
            CommonLikeUser user = new CommonLikeUser();

            user.setTargetUserId(visitor.getVisitorUserId());
            user.setScore(queryScore(userId, user.getTargetUserId()));

            commonUserList.add(user);
        }

        Integer pages = (int) Math.ceil(count * 1.0 / pagesize);
        return new PageResult<>(count, pagesize, pages, page, commonUserList);
    }

    /**
     *
     * @param userId     用户id
     * @param likeUserId 将要取消喜欢的用户id
     */
    @Override
    public void delete(Long userId, Long likeUserId) {

        Query query = Query.query(Criteria.where("userId").is(userId)
                .and("likeUserId").is(likeUserId));
        mongoTemplate.remove(query, UserLike.class);

    }


    /**
     * 查询两个用户之间的缘分值
     *
     * @param userId       用户id
     * @param targetUserId 目标用户id
     * @return 缘分值得分
     */
    private Double queryScore(Long userId, Long targetUserId) {
        Query query = new Query(Criteria.where("toUserId").is(userId).and("userId").is(targetUserId));
        RecommendUser recommendUser = mongoTemplate.findOne(query, RecommendUser.class);
        if (recommendUser == null) {
            return 95D;
        }

        return recommendUser.getScore();
    }
}